package com.luxk.db.storage.impl;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;

import com.luxk.db.common.ImpactException;
import com.luxk.db.errorcode.ErrorCodeStorage;
import com.luxk.db.storage.StorageUnit;

public class DefaultStorageUnit implements StorageUnit {
	
	private DefaultStorageGroup group = null;
	private String name = null;
	private RandomAccessFile file = null;
	private FileChannel channel = null;

	public DefaultStorageUnit(DefaultStorageGroup group, String name)
			throws ImpactException {
		this.group = group;
		this.name = name;
	}

	@Override
	public void open() throws ImpactException {
		String path = group.getAbsolutePath() + File.separator + name;
		
		if(this.file != null)
			throw new ImpactException(ErrorCodeStorage.ERROR_FILE_ALREADY_OPEN,
					path);
		
		try {
			this.file = new RandomAccessFile(path, "rws");
			this.channel = this.file.getChannel();
		} catch(FileNotFoundException e) {
			throw new ImpactException(ErrorCodeStorage.ERROR_OPEN_FILE, path);
		}
	}

	@Override
	public void close() throws ImpactException {
		try {
			if(this.channel != null) this.channel.close();
			this.channel = null;
			
			if(this.file != null) this.file.close();
			this.file = null;
		} catch(IOException e) {
			throw new ImpactException(ErrorCodeStorage.ERROR_CLOSE_FILE,
					this.group.getAbsolutePath() + File.separator + this.name);
		}
	}

	@Override
	public int read(byte[] b, long offset, int length) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int write(byte[] b, long offset, int length) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public Object readAsync(byte[] b, long offset, int length) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object writeAsync(byte[] b, long offset, int length) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void sync() {
		// TODO Auto-generated method stub
	}

	@Override
	public String getName() {
		return this.name;
	}

	@Override
	public long size() throws ImpactException {
		if(this.file == null) return -1;
		
		try {
			return this.file.length();
		} catch(IOException e) {
			throw new ImpactException(ErrorCodeStorage.ERROR_INVALID_FILE_SIZE,
					this.group.getAbsolutePath() + File.separator + this.name);
		}
	}

	public void create(String name, String parentPath) throws ImpactException {
		File me = new File(parentPath + File.separator + name);
		if(me.exists()) {
			throw new ImpactException(ErrorCodeStorage.ERROR_CREATE_FILE, 
					me.getAbsolutePath());
		}
		
		try {
			if(!me.createNewFile()) {
				throw new ImpactException(ErrorCodeStorage.ERROR_CREATE_FILE,
						me.getAbsolutePath());
			}
		} catch(IOException e) {
			throw new ImpactException(ErrorCodeStorage.ERROR_CREATE_FILE,
					me.getAbsolutePath(), e);
		}
	}

	public void drop() throws ImpactException {
		close();
		
		File me = new File(
				this.group.getAbsolutePath() + File.separator +	this.name);
		
		if(!me.delete()) {
			throw new ImpactException(ErrorCodeStorage.ERROR_DELETE,
					me.getAbsolutePath());
		}
	}
}
